import React from 'react';
import _ from 'underscore';
import cx from 'classnames';
import moment from 'moment';

import View from 'lib/View.jsx';
import format from 'lib/util/format';
import Card from 'lib/components/card.jsx';
import Card2 from 'lib/components/Card2.jsx';
import Select from 'lib/components/Select.jsx';
import DropdownList from 'lib/components/DropdownList.jsx';
import ChartWidget from 'lib/components/ChartWidget.jsx';
import GridWidget from 'lib/components/GridWidget.jsx';
import DefaultNoDataElement from 'lib/util/defaultNoDataElement.jsx';

import Loading from 'lib/components/Loading.jsx';
import DateRangePickerEnhanced from '../common/DateRangePickerEnhanced.jsx';
import DateComparerPickerEnhanced from '../common/DateComparerPickerEnhanced.jsx';

import Baner from './Baner/MainView.jsx';
import EventIndicator from './EventIndicator/MainView.jsx';
import ViewDimension from './ViewDimension/MainView.jsx';
import Conditions from './Conditions/MainView.jsx';
import EventTable from './EventTable/MainView.jsx';
import RootScope from './RootScope.es6';
import queryStore from 'lib/util/QueryStore.es6';

const dateTypeList = {
  hour: '按小时',
  day: '按天',
  week: '按周',
  month: '按月'
};

export default class RootView extends View {
  selectEventsChangedHandler(list) {
    this.dispatcher.dispatch({
      $type: 'events_changed',
      list
    });
  } // selectEventsChangedHandler

  chartTypeChangeHandler(newType) {
    this.dispatcher.dispatch({
      $type: 'change_chart_type',
      newType
    });
  } // chartTypeChangeHandler

  dateTypeChangeHandler(dateType) {
    this.dispatcher.dispatch({
      $type: 'change_date_type',
      dateType
    });
  } // dateTypeChangeHandler

  toggleComparer() {
    this.dispatcher.dispatch({
      $type: 'toggle_comparer'
    });
  } // toggleComparer

  completeDateHandler(data) {
    this.dispatcher.dispatch({
      $type: 'set_date',
      data
    });
  } // completeDateHandler

  completeComparerDateHandler(data) {
    this.dispatcher.dispatch({
      $type: 'set_date_comparer',
      data
    });
  } // completeComparerDateHandler

  showDataGridTotalChangeHandler({ target: { checked } }) {
    this.dispatcher.dispatch({
      $type: 'show_data_grid_total',
      checked
    });
  } // showDataGridTotalChangeHandler

  toggleEventTableTypeHandler(tableType) {
    this.dispatcher.dispatch({
      $type: 'switch_event_table_type',
      tableType
    })
  } // toggleEventTableTypeHandler

  renderCondition() {
    return (
      <div className="box">
        <Card title="分析条件">
          <Baner
            title={ this.title }
            favoriteName={ this.state.favoriteName }
            events={ this.state.data.eventIndicators.map(p => p.event) }
            favoriteId={ this.state.favoriteId }
            favoriteName={ this.state.favoriteName }
            percentValue={ this.state.chart0Settings.percent }
            eventIndicatorNames={ this.state.basicData.eventIndicatorNames }
            viewDimensionDic={ this.state.basicData.viewDimensionDic }
            alias={ this.state.date.alias }
            chartParameter={ this.scope.immutableParameter ? this.scope.immutableParameter.toJS() : null } />
          <EventIndicator
            height={ 38 }
            store={ this.state.events }
            properties={ this.state.properties }
            eventIndicators={ this.state.data.eventIndicators } />
          <ViewDimension
            height={ 38 }
            store={ this.state.viewDimensionOptions }
            viewDimensions={ this.state.data.viewDimensions } />
          <Conditions
            height={ 38 }
            store={ this.state.filterConditionOptions }
            filterConditions={ this.state.data.filterConditions } />
        </Card>
      </div>
    );
  } // renderCondition

  renderChartCondition() {
    return (
      <div className="pure-g chart-baner">
        <div className="pure-u-1">
          <DateRangePickerEnhanced
            canHaveCustom={ true }
            isNatural={ this.state.date.isNatural }
            isCustom={ this.state.date.isCustom }
            spanTime={ this.state.date.picker.spanTime }
            endTime={ this.state.date.picker.endTime }
            alias={ this.state.date.alias }
            onCompleted={ this.completeDateHandler.bind(this) } />
          <label style={{ display: 'inline-block', margin: '0px 10px', cursor: 'pointer' }}>
            <input type="checkbox" checked={ this.state.showCopmarer } onChange={ this.toggleComparer.bind(this) } />
            <span>对比</span>
          </label>
          {
            this.state.showCopmarer
              ? (
                <DateComparerPickerEnhanced
                  spanTime={ this.state.date.comparer.spanTime }
                  endTime={ this.state.date.comparer.endTime }
                  onCompleted={ this.completeComparerDateHandler.bind(this) } />
              ) : null
          }
          <div className="float-right">
            <div className="pure-g">
              <div className="pure-u-1">
                {
                  this.state.chart0Settings.showChart0
                    ? (
                      <div className="component-group">
                        <div className="icon-group">
                          <div
                            className={ cx('iconfont', {
                              selected: this.state.chart0Settings.chartType === 'line'
                            }) }
                            onClick={ this.chartTypeChangeHandler.bind(this, 'line') }>
                            &#xe642;
                          </div>
                          <div
                            className={ cx('iconfont', {
                              selected: this.state.chart0Settings.chartType === 'column'
                            }) }
                            onClick={ this.chartTypeChangeHandler.bind(this, 'column') }>
                            &#xe6c1;
                          </div>
                        </div>
                        <div className="icon-group">
                          <div
                            className={ cx('iconfont', {
                              selected: this.state.chart0Settings.chartType === 'pie'
                            }) }
                            onClick={ this.chartTypeChangeHandler.bind(this, 'pie') }>
                            &#xe6c2;
                          </div>
                        </div>
                      </div>
                    ) : null
                }
                <div className="switch-group component-group" style={{ marginRight: '0px' }}>
                  <button
                    key="hourly"
                    onClick={ this.dateTypeChangeHandler.bind(this, 'hour') }
                    className={ cx({
                      active: this.state.chart0Settings.dateType === 'hour',
                      disabled: this.state.chart0Settings.dateType === 'hour'
                    }) }
                    style={{
                      display: true ? 'block' : 'none',
                      cursor: false ? 'not-allowed' : 'pointer'
                    }}>
                    时
                  </button>
                  <button
                    key="daily"
                    onClick={ this.dateTypeChangeHandler.bind(this, 'day') }
                    className={ cx({
                      active: this.state.chart0Settings.dateType === 'day',
                      disabled: this.state.chart0Settings.dateType === 'day'
                    }) }
                    style={{
                      display: true ? 'block' : 'none',
                      cursor: false ? 'not-allowed' : 'pointer'
                    }}>
                    日
                  </button>
                  <button
                    key="weekly"
                    onClick={ this.dateTypeChangeHandler.bind(this, 'week') }
                    className={ cx({
                      active: this.state.chart0Settings.dateType === 'week',
                      disabled: this.state.chart0Settings.dateType === 'week'
                    }) }
                    style={{
                      display: true ? 'block' : 'none',
                      cursor: false ? 'not-allowed' : 'pointer'
                    }}>
                    周
                  </button>
                  <button
                    key="monthly"
                    onClick={ this.dateTypeChangeHandler.bind(this, 'month') }
                    className={ cx({
                      active: this.state.chart0Settings.dateType === 'month',
                      disabled: this.state.chart0Settings.dateType === 'month'
                    }) }
                    style={{
                      display: true ? 'block' : 'none',
                      cursor: false ? 'not-allowed' : 'pointer'
                    }}>
                    月
                  </button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    );
  } // renderChartCondition

  renderDoublePieChart() {
    let queryParams = queryStore.get();

    return (
      <div className="pure-g">
        <div className="pure-u-1-2">
          <ChartWidget
            key={ `pie-${ this.state.chart0Settings.pieChart0Key }-${ this.state.chart0Settings.dateType }-l` }
            height={ 400 }
            store={ this.state.chartPie0 }
            chartType={ this.state.chart0Settings.chartType }
            tooltipFormat={ this.scope.tooltipFormat }
            chartSettings={ _.extend(this.state.chart0Settings.settings, this.scope.legendSetting()) } />
          <div className="text-align-center">{ `${queryParams.from_date} ~ ${queryParams.to_date}` }</div>
        </div>
        <div className="pure-u-1-2">
          <ChartWidget
            key={ `pie-${ this.state.chart0Settings.pieChart0Key }-${ this.state.chart0Settings.dateType }-r` }
            height={ 400 }
            store={ this.state.chartPie0.data ? { data: this.state.chartPie0.data1 } : this.state.chartPie0 }
            chartType={ this.state.chart0Settings.chartType }
            tooltipFormat={ this.scope.tooltipFormat }
            chartSettings={ _.extend(this.state.chart0Settings.settings, this.scope.legendSetting()) } />
          <div className="text-align-center">{ `${queryParams.compare_from_date} ~ ${queryParams.compare_to_date}` }</div>
        </div>
      </div>
    );
  } // renderDoublePieChart

  renderSingleChart() {
    return (
      <ChartWidget
        key={ (this.state.chart0Settings.chartType === 'pie' ?  `pie-${ this.state.chart0Settings.pieChart0Key }` : this.state.chart0Settings.chartType) + this.state.chart0Settings.dateType }
        height={ 400 }
        store={ this.state.chart0Settings.chartType === 'pie' ?  this.state.chartPie0 : this.state.chart0 }
        chartType={ this.state.chart0Settings.chartType }
        tooltipFormat={ this.state.chart0Settings.chartType === 'pie' ?  this.scope.tooltipFormat : this.scope.tooltipFormatLine  }
        chartSettings={ _.extend(this.state.chart0Settings.settings, this.scope.legendSetting()) } />
    );
  } // renderSingleChart

  renderNoGroup() {
    return (
      <div className="default-nodata" style={{
        height: 400,
        lineHeight: '400px'
      }}>
        饼图只适用于有分组的查询
      </div>
    );
  } // renderNoGroup

  filterPieSeries(_series) {
    let series = _series.filter(p => _.some(this.state.selectedColumns, r => p.get('name').indexOf(r) !== -1)).toJS();

    if (series.length !== _series.count()) {
      let list = _series.filterNot(p =>
        _.some(this.state.selectedColumns, r => p.get('name').indexOf(r) !== -1)).toJS();
      let sumY = _.chain(list)
                  .map(p => p.data)
                  .flatten(true)
                  .reduce((x, y) => x + y.y, 0)
                  .value();
      let sumYValue = _.chain(list)
                       .map(p => p.data)
                       .flatten(true)
                       .reduce((x, y) => x + y.customData.y.yValue || 0, 0)
                       .value();
      let firstX = list[0].data[0].x;

      let otherSerie = {
        id: 10000,
        name: '其它...',
        data: [
          {
            x: firstX,
            y: sumY,
            customData: {
              y: {
                label: '其它...',
                yValue: sumYValue,
                fmtVal: format.rate(sumY)
              }
            }
          }
        ]
      };

      series.push(otherSerie);

      _.each(series, p => p.name += ` ${ p.data[0].customData.y.fmtVal }`);
    }

    return series;
  } // filterPieSeries

  renderChart() {
    let showChart0Ex = true;
    if (this.state.chart0.data && this.state.chart0Settings.showChart0 && this.state.showSelectedColumns) {
      if (this.state.chart0Settings.chartType === 'pie') {
        if (_.size(this.state.chart0.data) === 1) {
          showChart0Ex = false;
        } else if (this.state.chartPie0.data) {
          this.state.chartPie0.data.series = this.filterPieSeries(this.state.chartPie0._series);

          if (this.state.chartPie0.data1) {
            this.state.chartPie0.data1.series = this.filterPieSeries(this.state.chartPie0._series1);
          }
        }

        showChart0Ex = this.state.chartPie0.data ? this.state.chartPie0.data.series.length : false;
      } else {
        if (_.size(this.state.chart0.data) === 1) {
          showChart0Ex = false;
        } else {
          this.state.chart0.data.series =
            this.state.chart0._series.filter(p => _.some(this.state.selectedColumns, r => p.get('name').indexOf(r) !== -1)).toJS();

          showChart0Ex = this.state.chart0.data.series.length;
        }
      }
    }

    return (
      this.state.chart0Settings.showChart0
        ? (
          <div className="box">
            <Card title={ this.title }>
              {
                showChart0Ex
                  ? this.renderChartCondition()
                  : null
              }
              {
                showChart0Ex
                  ? (
                    <div className="pure-u-1" style={{ marginTop: 10 }}>
                      {
                        this.state.showCopmarer && this.state.chart0Settings.chartType === 'pie'
                          ? (
                            _.size(this.state.basicData.viewDimensionDic)
                              ? this.renderDoublePieChart()
                              : this.renderNoGroup()
                          ) : (
                            this.state.chart0Settings.chartType === 'pie' && !_.size(this.state.basicData.viewDimensionDic)
                              ? this.renderNoGroup()
                              : this.renderSingleChart()
                          )
                      }
                    </div>
                  ) : null
              }
              {
                !showChart0Ex
                  ? (
                    <DefaultNoDataElement />
                  ) : null
              }
            </Card>
          </div>
        ) : null
    );
  } // renderChart

  render() {
    this.title = _.filter([
      this.state.chart0Settings.char0Name,
      dateTypeList[this.state.chart0Settings.dateType],
      this.state.chart0Settings.viewDimensions
    ], p => p).join('，') + '查看';

    let totalAction = () => (
      <label style={{ fontWeight: 'normal' }}>
        <input
          type="checkbox"
          checked={ this.state.showDataGridTotal }
          onChange={ this.showDataGridTotalChangeHandler.bind(this) }/>
      <span style={{ marginLeft: 10 }}>合计</span>
      </label>
    );
    let countAction = extClassName => (
      <div className={ 'card-extra-container ' + extClassName }>
        <span style={{ fontWeight: 'normal' }}>共 </span>
        <span style={{ fontWeight: 'normal' }}>
          { _.size(this.state.dataGrid.data)
              ? this.state.dataGrid.data.rows.length
              : 0 }
        </span>
        <span style={{ fontWeight: 'normal' }}> 组数据</span>
      </div>
    );

    let attributes = {};
    if (this.state.dataGrid.data) {
      if (this.state.chart0Settings.showChart0) {
        attributes = {
          className: 'dynamic-title widget-normal',
          title: totalAction(),
          extra: countAction('')
        };
      } else {
        attributes = {
          className: 'dynamic-title widget-normal',
          title: this.title
        };
      }
    }

    let date = this.state.date;
    return (
      <div>
        { this.renderCondition() }
        { this.renderChart() }
        <div className="box">
          <Card { ...attributes }>
            {
              this.state.chart0Settings.showChart0
                ? null
                : this.renderChartCondition()
            }
            {
              !this.state.chart0Settings.showChart0 && this.state.dataGrid.data ? (
                <div className="pure-g event-table-baner">
                  <div className="pure-u-1-2">{ totalAction() }</div>
                  <div className="pure-u-1-2">{ countAction('float-right') }</div>
                </div>
              ) : null
            }
            {
              !this.state.showCopmarer ? null : (
                <div className="pure-g" style={{ margin: '20px auto' }}>
                  <div className="pure-u-1">
                    <button
                      className={ cx('btn btn-h-gray', {
                        active: this.state.showEventTableType === 'current'
                      })}
                      onClick={
                        this.state.showEventTableType === 'current'
                          ? null
                          : this.toggleEventTableTypeHandler.bind(this, 'current')
                      }>
                      { moment(date.picker.endTime - date.picker.spanTime).format('YYYY-MM-DD') }
                       <span style={{ margin: 'auto 5px' }}>至</span>
                      { moment(date.picker.endTime).format('YYYY-MM-DD') }
                    </button>
                    <button
                      style={{ margin: 'auto 10px' }}
                      className={ cx('btn btn-h-gray', {
                        active: this.state.showEventTableType === 'comparer'
                      })}
                      onClick={
                        this.state.showEventTableType === 'comparer'
                          ? null
                          : this.toggleEventTableTypeHandler.bind(this, 'comparer')
                      }>
                      { moment(date.comparer.endTime - date.comparer.spanTime).format('YYYY-MM-DD') }
                       <span style={{ margin: 'auto 5px' }}>至</span>
                      { moment(date.comparer.endTime).format('YYYY-MM-DD') }
                    </button>
                    <button
                      className={ cx('btn btn-h-gray', {
                        active: this.state.showEventTableType === 'meta'
                      })}
                      onClick={
                        this.state.showEventTableType === 'meta'
                          ? null
                          : this.toggleEventTableTypeHandler.bind(this, 'meta')
                      }>
                      对比事件变化率
                    </button>
                  </div>
                </div>
              )
            }
            <EventTable
              eventIndicators={ this.state.basicData.eventIndicatorNames }
              dimensionDic={ this.state.basicData.viewDimensionDic }
              cols={ this.state.dataGridColumns }
              noData={ p => p.data ? !_.size(p.data) : true }
              showSelectedColumns={ this.state.showSelectedColumns }
              selectedColumns={ this.state.selectedColumns }
              store={ this.state.dataGrid } />
          </Card>
        </div>
      </div>
    );
  } // render
}

RootView.defaultProps = {
  Scope: RootScope
}
